package utils

import (
	"bytes"
	"crypto/md5"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"golang.org/x/crypto/scrypt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"sort"
	"strings"
	"time"
)

var (
	salt        string
	trueBaseUrl = "https://10.11.22.98:8082/"
)

func SetSalt(s string) { salt = s }

//  加密
func SaltPwd(pwd string) string {
	for i := 0; i < 10; i++ {
		if k, err := scrypt.Key([]byte(pwd), []byte(salt), 16384, 8, 1, 32); err == nil {
			m5 := md5.New()
			m5.Write(k)
			return hex.EncodeToString(m5.Sum(nil))
		}
	}
	return salt + pwd
}

func NewToken(username, pwd string, t time.Time) string {
	var buf bytes.Buffer
	m5 := md5.New()
	buf.WriteString(username)
	buf.WriteString(pwd)
	buf.WriteString(t.Format("2006-01-02 15:04:05"))
	m5.Write([]byte(buf.String()))
	return hex.EncodeToString(m5.Sum(nil))
}

func NewSign(name, idcode, key string) string {
	var buf bytes.Buffer
	m5 := md5.New()
	buf.WriteString(idcode)
	buf.WriteString(name)
	buf.WriteString(key)
	m5.Write([]byte(buf.String()))
	return hex.EncodeToString(m5.Sum(nil))
}

func NewSchoolSign(college, degree, enyear, name, idcode, key string) string {
	var buf bytes.Buffer
	m5 := md5.New()
	buf.WriteString(college)
	buf.WriteString(degree)
	buf.WriteString(enyear)
	buf.WriteString(idcode)
	buf.WriteString(name)
	buf.WriteString(key)
	m5.Write([]byte(buf.String()))
	return hex.EncodeToString(m5.Sum(nil))
}

type GetSignInfo struct {
	Args_1 string
	Args_2 string
	Args_3 string
	Args_4 string
	Date   time.Time
}

func InfoToSign(a *GetSignInfo) string {
	var buf bytes.Buffer
	m5 := md5.New()
	buf.WriteString(a.Args_1)
	buf.WriteString(a.Args_2)
	buf.WriteString(a.Args_3)
	buf.WriteString(a.Args_4)
	//buf.WriteString(a.Date.Format("2006-01-02 15:04:05"))
	m5.Write([]byte(buf.String()))
	return hex.EncodeToString(m5.Sum(nil))
}

func Sub_suffix(s string, N int) string {

	if len(s) <= N {
		return s
	}
	ss, sl, rl, rs := "", 0, 0, []rune(s)
	for _, r := range rs {
		rint := int(r)
		if rint < 128 {
			rl = 1
		} else {
			rl = 2
		}
		if sl+rl > N {
			break
		}
		sl += rl
		ss += string(r)
	}
	return ss + "..."
}

// return md5 str
func Md5(text string) string {
	hashMd5 := md5.New()
	io.WriteString(hashMd5, text)
	return fmt.Sprintf("%x", hashMd5.Sum(nil))
}

// 数组的排序后的MD5值
func ArrayMd5(array []string) string {
	sort.Strings(array)
	hashMd5 := md5.New()
	io.WriteString(hashMd5, strings.Join(array, ""))
	return fmt.Sprintf("%x", hashMd5.Sum(nil))
}

// return  sha1 str
func Sha1(data string) string {
	s1 := sha1.New()
	s1.Write([]byte(data))
	return fmt.Sprintf("%x", s1.Sum(nil))
}
func Sha1_new(data string) string {
	t := sha1.New()
	io.WriteString(t, data)
	return fmt.Sprintf("%x", t.Sum(nil))
}

// 数组的排序后的哈希值
func ArraySha1(array []string) string {
	sort.Strings(array)
	s := sha1.New()
	io.WriteString(s, strings.Join(array, ""))
	return fmt.Sprintf("%x", s.Sum(nil))
}

//GetIp 获取ip地址
func GetIp(condition string) string {
	var ipv4addr string
	switch condition {
	default:
		addrs, err := net.InterfaceAddrs()
		if err != nil {
			log.Println("Oops:=", err)
		} else {
			for _, add := range addrs {
				if ipnet, ok := add.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
					if ipnet.IP.To4() != nil {
						log.Println("Ipv4:=", ipnet.IP.String())
						ipv4addr = ipnet.IP.String()
					}
				}
			}
		}
	case "production", "testing":
		resp, err := http.Get("http://myexternalip.com/raw")
		if err != nil {
			log.Println("getIp err=", err)
			return trueBaseUrl
		}
		str, _ := ioutil.ReadAll(resp.Body)

		ipv4addr = string(str)
	}
	return ipv4addr
}
func DecodeJsonhttpResponse(r io.Reader, v interface{}) error {
	body, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}

	body2 := body
	buf := bytes.NewBuffer(make([]byte, 0, len(body2)+1024))
	if err := json.Indent(buf, body2, "", "    "); err == nil {
		body2 = buf.Bytes()
	}
	log.Printf("[WECHAT_DEBUG] [API] http response body:\n%s\n", body2)

	return json.Unmarshal(body, v)
}
